package jacktgq.fractalImage.sierpinskiTriangle;

import jacktgq.AlgoVisHelper;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Path2D;

public class AlgoFrame extends JFrame{
    private int canvasWidth;
    private int canvasHeight;

    private FractalData fractalData;
    public AlgoCanvas canvas;

    public AlgoFrame(String title, int width, int height, FractalData fractalData){
        super(title);
        this.canvasWidth = width;
        this.canvasHeight = height;
        this.fractalData = fractalData;

        canvas = new AlgoCanvas();
        setContentPane(canvas);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //setSize(width + 16, height + 39);
        setSize(width + 6, height + 29);
        setResizable(false);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public void render(FractalData fractalData) {
        this.fractalData = fractalData;
        canvas.repaint();
    }

    public class AlgoCanvas extends JPanel {
        public AlgoCanvas() {
            // 双缓存
            super(true);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            // 抗锯齿
            RenderingHints hints = new RenderingHints(
                    RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.addRenderingHints(hints);
            // 具体绘制
            drawFractal(g2d, 0, canvasHeight, canvasWidth, 0);
        }

        /**
         *
         * @param g2d
         * @param Ax        ：等边三角形左下角顶点的横坐标
         * @param Ay        ：等边三角形左下角顶点的纵坐标
         * @param side      ：等边三角形的边长
         * @param depth     ：递归深度
         */
        private void drawFractal(Graphics2D g2d, double Ax, double Ay, int side, int depth) {
            if (side <= 1) {
                AlgoVisHelper.fillRectangle(g2d, Ax, Ay, 1, 1);
                return;
            }

            double Bx = Ax + side;
            double By = Ay;
            double Cx = Ax + side / 2;
            double Cy = Ay - side * Math.sin(Math.PI / 3);

            if (depth == fractalData.getDepth()) {
                AlgoVisHelper.fillTriangle(g2d, Ax, Ay, Bx, By, Cx, Cy);
            }

            double AB_centerX = (Ax + Bx) / 2;
            double AB_centerY = (Ay + By) / 2;
            double AC_centerX = (Ax + Cx) / 2;
            double AC_centerY = (Ay + Cy) / 2;

            drawFractal(g2d, Ax, Ay, side / 2, depth + 1);
            drawFractal(g2d, AB_centerX, AB_centerY, side / 2, depth + 1);
            drawFractal(g2d, AC_centerX, AC_centerY, side / 2, depth + 1);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(canvasWidth, canvasHeight);
        }
    }
}


